package br.com.me.ceap.down;

import br.com.me.ceap.BaseMojo;
import br.com.me.ceap.MECEAPUtils;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.installer.ArtifactInstallationException;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.artifact.ProjectArtifactMetadata;
import org.codehaus.plexus.digest.Digester;
import org.codehaus.plexus.util.FileUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;

/**
 * Goal which download Custom Root JAR and install (directly/forcibly) on maven's local repositorys
 *
 * @goal downloadCustomRootJAR
 * @requiresProject
 */
public class DownloadCustomRootJARMojo extends BaseMojo {
// ------------------------------ FIELDS ------------------------------

    /**
     * Project Directory
     *
     * @parameter default-value="${basedir}"
     * @required
     * @readonly
     */
    private File projectDirectory;
    /**
     * Local Repository Directory
     *
     * @parameter default-value="${basedir}/extra"
     * @required
     */
    private File localRepositoryPath;
    /**
     * The type of remote repository layout to install to. Try <code>legacy</code> for a Maven 1.x-style repository
     * layout.
     *
     * @parameter expression="${repositoryLayout}" default-value="default"
     * @required
     * @readonly
     */
    private String repositoryLayout;
    /**
     * Map that contains the repository layouts.
     *
     * @component role="org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout"
     */
    private Map repositoryLayouts;
    /**
     * Digester for SHA-1.
     *
     * @component role-hint="sha1"
     */
    private Digester sha1Digester;

    private static final String jar_groupId = "br.com.me.ceap";
    private static final String jar_packaging = "jar";

// ------------------------ INTERFACE METHODS ------------------------


// --------------------- Interface mojo ---------------------

    private String getPathWithoutFileName(String path) {
        int posLastSep = path.lastIndexOf(File.separator);
        return path.substring(0, posLastSep);
    }

    private void generateSHA1(String pathFile) throws MojoExecutionException {
        this.getLog().debug("Generating checksum sha1 for " + pathFile);
        try {
            File jarFile = new File(pathFile);
            String sum = sha1Digester.calc(jarFile);
            File target = new File(this.getPathWithoutFileName(jarFile.getPath()), jarFile.getName() + ".sha1");
            FileUtils.fileWrite(target.getAbsolutePath(), sum);
            this.getLog().debug("Generated " + target.getPath());
        } catch (Exception ex) {
            throw new MojoExecutionException("Error calculating digest. " + ex);
        }
    }

    public void execute() throws MojoExecutionException, MojoFailureException {
        this.getLog().debug("Preparing to download the customRoot jar");
        WebClient webClient = MECEAPUtils.forDownloadCustomRootJAR(this);

        this.getLog().info("Downloading CustomRoot jar file");
        Attachment attachment = webClient.get(Attachment.class);

        try {
            File jarFile = File.createTempFile(this.getCustomRootName(), ".jar");
            String jarFileName = jarFile.getPath();

            FileOutputStream fileOutputStream = new FileOutputStream(jarFileName);
            IOUtils.copy(attachment.getDataHandler().getInputStream(), fileOutputStream);
            fileOutputStream.close();

            this.getLog().debug("Downloaded " + jarFileName);

            this.getLog().debug("Creating artifact");
            Artifact artifact = artifactFactory.createArtifactWithClassifier(
                    jar_groupId, this.getCustomRootName(), version, jar_packaging, this.classifier);

            this.getLog().debug("Generating Pom File");
            File generatedPomFile = this.generatePomFile(jar_groupId, version, jar_packaging);
            try {
                ArtifactMetadata pomMetadata = new ProjectArtifactMetadata(artifact, generatedPomFile);
                artifact.addMetadata(pomMetadata);
                this.getLog().debug("Generating ArtifactRepositoryLayout");
                this.getLog().info(String.format("Installing to local repos at: %s", localRepository.getBasedir()));
                installer.install(new File(jarFileName), artifact, localRepository);
            } finally {
                generatedPomFile.delete();
                jarFile.delete();
            }
        } catch (IOException e) {
            throw new MojoExecutionException(e.getMessage(), e);
        } catch (ArtifactInstallationException e) {
            throw new MojoExecutionException(e.getMessage(), e);
        }
    }
}
